package OnlineLibrary.WebSite;

import java.util.Properties;

import javax.servlet.ServletContextEvent;

import org.apache.log4j.Logger;
import org.omg.CORBA.ORB;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContext;
import org.omg.CosNaming.NamingContextHelper;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.InvalidName;
import org.omg.CosNaming.NamingContextPackage.NotFound;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.POAManager;
import org.omg.PortableServer.POAManagerPackage.AdapterInactive;

import be.fundp.info.util.logging.MyLogger;

import OnlineLibrary.managers.AuctionMgr;
import OnlineLibrary.managers.CatalogMgr;
import OnlineLibrary.managers.DeliveryMgr;
import OnlineLibrary.managers.NotificationBuyingMgr;
import Util.Util;

/**
 * Manager automatically launched when the server is starting 
 *
 */
public class mainManager implements javax.servlet.ServletContextListener {
	private static Logger logger = MyLogger.getLogger(Class.class);
	private static final String log4j = "log4j.properties";
	private final String file =  "OnlineLibrary.properties";
	private ORB orb;
	
	private static AuctionMgr auctionMgr = null;
	private static CatalogMgr catalogMgr = null;
	private static DeliveryMgr deliveryMgr = null;

	public static AuctionMgr getAuctionMgr() {
		if (auctionMgr == null)
			auctionMgr = new AuctionMgr();
		return auctionMgr;

	}
	
	public static CatalogMgr getCatalogMgr() {
		if (catalogMgr == null)
			catalogMgr = new CatalogMgr();
		return catalogMgr;

	}
	
	public static DeliveryMgr getDeliveryMgr() {
		if (deliveryMgr == null)
			deliveryMgr = new DeliveryMgr();
		return deliveryMgr;

	}

	@Override
	public void contextDestroyed(ServletContextEvent arg0) {
		// TODO Auto-generated method stub

	}

	/**
	 * Method calls when server is starting
	 */
	@Override
	public void contextInitialized(ServletContextEvent arg0) {
		try {
			//activate all library managers
			launchNotificationBuyingMgr();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
	
	/**
	 * Activate all library managers
	 * @throws NotFound
	 * @throws CannotProceed
	 * @throws InvalidName
	 */
	private void launchNotificationBuyingMgr() throws NotFound, CannotProceed, InvalidName{
		if(!MyLogger.isConfigured())
			MyLogger.initLogger(log4j);
		logger = MyLogger.getLogger(Class.class);
		
		String ip = Util.getPropertiesAttribute(file, "ip");
		String port = Util.getPropertiesAttribute(file, "port");
		
		if(ip == null || port == null){
			logger.info("[ERROR] file "+file+ " is absent");
			return;
		}
	



		// build properties for orb
		Properties props = new Properties();
		props.put("org.omg.CORBA.ORBInitialHost", ip);
		props.put("org.omg.CORBA.ORBInitialPort", port);

		// initialize ORB and rootPOA
		orb = ORB.init(new String[] { "-ORBInitialPort", port, "-ORBInitiaHost", ip }, props);
		POA rootPOA = null;

		try {
			rootPOA = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
		} catch (org.omg.CORBA.ORBPackage.InvalidName e) {
			logger.fatal("unable to resolve rootpoa, exiting.\n", e);
			System.exit(1);
		}

		// get naming service reference (using RootPOA)
		NamingContext naming = NamingContextHelper.narrow(orb.string_to_object("corbaloc:iiop:" + ip + ":" + port + "/NameService"));

		NameComponent[] name = new NameComponent[] { new NameComponent("Library", "Object") };
		// create servant
		NotificationBuyingMgr NotifMgr_impl = new NotificationBuyingMgr(getDeliveryMgr());
		logger.info("Delivery launched");
		try {
			rootPOA.activate_object(NotifMgr_impl);
		} catch (Exception e) {
			logger.error(e);
		}

		// bind object into the naming service
		try {
			naming.bind(name, NotifMgr_impl._this_object());
		} catch (Exception e) {
			naming.rebind(name, NotifMgr_impl._this_object());
			logger.fatal(e);
		} 
		logger.debug("published " + orb.object_to_string(NotifMgr_impl._this_object()));
		// get manager and activate it
		POAManager manager = rootPOA.the_POAManager();
		try {
			manager.activate();
		} catch (AdapterInactive e) {
			logger.fatal("cannot activate manager.\n", e);
			System.exit(1);
		}
		
		logger.info("NotifMgr launched");
		getAuctionMgr();
		logger.info("AuctionMgr launched");
		getCatalogMgr();
		logger.info("CatalogMgr launched");
		
		
		// block thread until orb is stopped
		logger.info("run orb, hang current thread.");
		Thread t = new Thread(){
			public void run(){
				orb.run();
			}
		};
		t.start();
	}

}
